package com.xb.sourest.im;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.util.Log;
import com.hyphenate.EMCallBack;
import com.hyphenate.EMConnectionListener;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMOptions;
import com.hyphenate.exceptions.HyphenateException;
import com.hyphenate.push.EMPushConfig;
import com.xb.sourest.AndroidApplication;
import com.xb.sourest.base.BuildParams;
import com.xb.sourest.im.common.FCCallBack;
import com.xb.sourest.im.common.FCError;
import com.xb.sourest.storge.db.DbOpenHelper;
import com.xb.sourest.storge.db.user.UserDao;
import com.xd.navi.ThreadManager;

import java.util.Iterator;
import java.util.List;

/**
 * 环信sdk初始化帮助类(除了聊天功能以外都在这里)
 */
public class HxSdkHelper {
    private static final String TAG = "HxSdkHelper";

    private HxSdkHelper() {
    }

    private static final class HxSdkHelperHolder {
        public static HxSdkHelper instance = new HxSdkHelper();
    }

    public static HxSdkHelper getInstance() {
        return HxSdkHelperHolder.instance;
    }

    private Context mAppContext;
    private boolean mIsSdkInited;
    private boolean mHasAsyncUserList;

    /**
     * 初始化环信sdk
     * 放在Application的onCreate()
     */
    public void initSdkOptions(Context context, boolean isDebug) {
        if (mIsSdkInited)
            return;
        mAppContext = context.getApplicationContext();

        // 如果APP启用了远程的service，此application:onCreate会被调用2次
        // 为了防止环信SDK被初始化2次，加此判断会保证SDK被初始化1次
        // 默认的APP会在以包名为默认的process name下运行，如果查到的process name不是APP的process name就立即返回
        int pid = android.os.Process.myPid();
        String processAppName = getAppName(pid);
        if (processAppName == null || !processAppName.equalsIgnoreCase(mAppContext.getPackageName()))
            return;

        //推送配置
        EMPushConfig.Builder builder = new EMPushConfig.Builder(mAppContext)
                .enableVivoPush() // 推送证书相关信息配置在AndroidManifest.xml中
          //      .enableMeiZuPush(String appId, String appKey)
                .enableMiPush(BuildParams.MIPUSH_APPID,BuildParams.MIPUSH_APPKEY)
         //       .enableOppoPush(String appKey, String appSecret)
                .enableHWPush(); //开发者需要调用该方法来开启华为推送
       //         .enableFCM(String senderId); //开发者需要调用该方法来开启FCM推送

        EMOptions options = new EMOptions();
        //设置AppKey
        options.setAppKey(BuildParams.EASEMOB_APPKEY);
        //添加好友需要验证 true代表不需要好友验证 直接添加
        options.setAcceptInvitationAlways(false);
        // 是否自动将消息附件上传到环信服务器，默认为True是使用环信服务器上传下载，如果设为 false，需要开发者自己处理附件消息的上传和下载
        options.setAutoTransferMessageAttachments(true);
        // 是否自动下载附件类消息的缩略图等，默认为 true 这里和上边这个参数相关联
        options.setAutoDownloadThumbnail(true);
        //不需要阅读回执 true代表需要有回执 ‘已读’
        options.setRequireAck(true);
        //不需要发送服务器回执
        options.setRequireDeliveryAck(false);
        //可以自动登录
        options.setAutoLogin(true);
        //设置推送配置
        options.setPushConfig(builder.build());

        EMClient.getInstance().init(mAppContext, options);
        EMClient.getInstance().setDebugMode(isDebug);
        mIsSdkInited = true;
        Log.i("HxSdk has inited", "------ hxSdk init ------");
    }

    private String getAppName(int pID) {
        String processName = null;
        ActivityManager am = (ActivityManager) mAppContext.getSystemService(Context.ACTIVITY_SERVICE);
        List l = am.getRunningAppProcesses();
        Iterator i = l.iterator();
        PackageManager pm = mAppContext.getPackageManager();
        while (i.hasNext()) {
            ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo) (i.next());
            try {
                if (info.pid == pID) {
                    CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA));
                    processName = info.processName;
                    return processName;
                }
            } catch (Exception e) {
            }
        }
        return processName;
    }


    /**
     * 注册方法
     * @param phone    手机号
     * @param pwd      密码
     * @param callBack 回调【注意回调会在子线程中】
     */
    public void regist(final String phone, final String pwd, final FCCallBack callBack) {
        ThreadManager.getInstance().addNewRunnable(new Runnable() {
            @Override
            public void run() {
                try {
                    EMClient.getInstance().createAccount(phone, pwd);
                    if (callBack != null)
                        callBack.onSuccess(null);
                } catch (HyphenateException e) {
                    Log.e("HxSdk Regster", "HxSdk regist from server fail : hxErrCode = " + e.getErrorCode() + " , msg = " + e.getMessage());
                    if (callBack != null)
                        callBack.onFail(FCError.REGIST_FAIL, FCError.getErrorMsgIdFromCode(e.getErrorCode()));
                }
            }
        });
    }


    /**
     * 手动登录环信的方法
     *
     * @param phone    手机号
     * @param pwd      密码
     * @param callBack 回调
     */
    public void login(final String phone, final String pwd, final FCCallBack callBack,String token) {
        EMClient.getInstance().login(phone, pwd, new EMCallBack() {
            @Override
            public void onSuccess() {
                Log.i("HxSdk login", "HxSdk login from server success");
                loadLoginData(phone,true);
                loadHxLocalData();
                if (callBack != null)
                    callBack.onSuccess(null);
            }

            @Override
            public void onError(int code, String msg) {
                Log.e("HxSdk login fail", "HxSdk login fail : hxErrCode = " + code + " , msg = " + msg);
                if (callBack != null)
                    callBack.onFail(FCError.LOGIN_FAIL, FCError.getErrorMsgIdFromCode(code));
            }

            @Override
            public void onProgress(int progress, String status) {

            }
        });
    }

    /**
     * 判断是否能自动登录
     */
    public boolean canAutoLogin() {
        return EMClient.getInstance().isLoggedInBefore();
    }

    /**
     * 加载环信本地数据
     */
    public void loadHxLocalData() {
        EMClient.getInstance().groupManager().loadAllGroups();
        Log.i("HxSdk load all groups", "HxSdk load all groups success");
        EMClient.getInstance().chatManager().loadAllConversations();
        Log.i("HxSdk load all conversation", "HxSdk load all conversation success");
    }


    /**
     * 同步登录用户信息
     */
    public void loadLoginData(String phone,boolean isLogin) {
        UserDao.getInstance().updateUserLoginSucess(phone,isLogin);
    }

    /**
     * 退出环信登录
     *
     * @param callBack 回调
     */
    public void logout(final FCCallBack callBack) {
        if (!EMClient.getInstance().isLoggedInBefore()) {
            if (callBack != null)
                callBack.onSuccess(null);
            return;
        }
        //方法里第一个参数需要设为true，这样退出的时候会解绑设备token，否则可能会出现退出了，还能收到消息的现象。
        EMClient.getInstance().logout(true, new EMCallBack() {
            @Override
            public void onSuccess() {
                resetFlags();
                //TodO()退出登录需要将本地数据库的是否登录置空
    //            loadLoginData();

                DbOpenHelper.getInstance(AndroidApplication.getApplication()).close();
                if (callBack != null)
                    callBack.onSuccess(null);
            }

            @Override
            public void onError(int i, String s) {
                resetFlags();
                DbOpenHelper.getInstance(AndroidApplication.getApplication()).close();
                if (callBack != null)
                    callBack.onFail(FCError.LOGOUT_FAIL, FCError.getErrorMsgIdFromCode(i));
            }

            @Override
            public void onProgress(int i, String s) {

            }
        });
    }

    //将某些标记位还原
    private void resetFlags() {
        mHasAsyncUserList = false;
    }

    /**
     * 获取当前登录的账号
     *
     * @return 当前登录账号
     */
    public String getCurLoginUser() {
        return EMClient.getInstance().getCurrentUser();
    }

    /**
     * 添加连接监听
     *
     * @param listener 环信连接监听
     */
    public void addConnectListener(EMConnectionListener listener) {
        if (listener != null)
            EMClient.getInstance().addConnectionListener(listener);
    }

    /**
     * 移除连接监听
     *
     * @param listener 环信连接监听
     */
    public void removeConnectListener(EMConnectionListener listener) {
        if (listener != null)
            EMClient.getInstance().removeConnectionListener(listener);
    }

    /**
     * 从环信服务器拉取好友列表【仅包含账号】
     *
     * @param callBack 回调
     */
    public void asyncUserListFromServer(final FCCallBack<List<String>> callBack) {
        if (mHasAsyncUserList) {
            Log.i(TAG, "HxSdk already has asynced user from server.");
            if (callBack != null)
                callBack.onSuccess(null);
            return;
        }

        ThreadManager.getInstance().addNewRunnable(new Runnable() {
            @Override
            public void run() {
                try {
                    List<String> userList = EMClient.getInstance().contactManager().getAllContactsFromServer();
                    Log.i(TAG, "HxSdk async user from server : " + userList);
                    mHasAsyncUserList = true;
                    if (callBack != null)
                        callBack.onSuccess(userList);
                } catch (HyphenateException e) {
                    Log.e(TAG, "HxSdk async user from server fail : hxErrCode = " + e.getErrorCode() + " , msg = " + e.getMessage());
                    if (callBack != null)
                        callBack.onFail(FCError.ASYNC_HXUSER_FAIL, FCError.getErrorMsgIdFromCode(e.getErrorCode()));
                }
            }
        });
    }

    /**
     * 添加好友事件监听
     */
    public void addContactListener(HxContactListener listener) {
        if (listener != null)
            EMClient.getInstance().contactManager().setContactListener(listener);
    }

    /**
     * 移除好友事件监听
     */
    public void removeContactListener(HxContactListener listener) {
        if (listener != null)
            EMClient.getInstance().contactManager().removeContactListener(listener);
    }

    /**
     * 添加好友
     *
     * @param phone 手机号
     * @throws HyphenateException 鬼知道什么异常
     */
    public void addFriend(String phone) throws HyphenateException {
        EMClient.getInstance().contactManager().addContact(phone, null);
    }

    /**
     * 删除好友
     *
     * @param phone 手机号
     * @throws HyphenateException 鬼知道什么异常
     */
    public void deleteFriend(String phone) throws HyphenateException {
        EMClient.getInstance().contactManager().deleteContact(phone);
    }


    /**
     * 同意好友请求
     *
     * @param phone    对方手机号
     * @param callBack 回调
     */
    public void agreeNewFriendInvite(String phone, final FCCallBack callBack) {
        EMClient.getInstance().contactManager().asyncAcceptInvitation(phone, new EMCallBack() {
            @Override
            public void onSuccess() {
                if (callBack != null)
                    callBack.onSuccess(null);
            }

            @Override
            public void onError(int i, String s) {
                if (callBack != null)
                    callBack.onFail(FCError.AGREE_INVITE_FAIL, FCError.getErrorMsgIdFromCode(i));
            }

            @Override
            public void onProgress(int i, String s) {

            }
        });
    }

    /**
     * 拒绝好友请求
     *
     * @param phone    对方手机号
     * @param callBack 回调
     */
    public void rejectNewFriendInvite(String phone, final FCCallBack callBack) {
        EMClient.getInstance().contactManager().asyncDeclineInvitation(phone, new EMCallBack() {
            @Override
            public void onSuccess() {
                if (callBack != null)
                    callBack.onSuccess(null);
            }

            @Override
            public void onError(int i, String s) {
                if (callBack != null)
                    callBack.onFail(FCError.REJECT_INVITE_FAIL, FCError.getErrorMsgIdFromCode(i));
            }

            @Override
            public void onProgress(int i, String s) {

            }
        });
    }


}
